package hapi.flash.util;

#if flash9
typedef NativeKeyboard = flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.Lib;
#elseif flash
typedef NativeKeyboard = flash.Key;
#end

class Keyboard {
	
	static var inst:Keyboard;
	
	public static var LEFT:KeyboardKey = new KeyboardKey(37);
	public static var UP:KeyboardKey = new KeyboardKey(38);
	public static var RIGHT:KeyboardKey = new KeyboardKey(39);
	public static var DOWN:KeyboardKey = new KeyboardKey(40);
	public static var SPACE:KeyboardKey = new KeyboardKey(NativeKeyboard.SPACE);
	public static var ENTER:KeyboardKey = new KeyboardKey(NativeKeyboard.ENTER);
	public static var SHIFT:KeyboardKey = new KeyboardKey(NativeKeyboard.SHIFT);
	public static var CTRL:KeyboardKey = new KeyboardKey(NativeKeyboard.CONTROL);
	
	var keys:IntHash<KeyboardKey>;
	
	function new() {
		initKeys();
		initListener();
	}
	
	public static function getKeyboard():Keyboard {
		if( inst == null )
			inst = new Keyboard();
		return inst;
	}
	
	public function registerKey( key:KeyboardKey ) {
		//if ( keys.exists( key.code ) ) throw "Keyboard Key is already registered - use Keyboard.getKey method to find KeyboardKey instance";
		keys.set( key.code, key );
	}
	
	public function getKey( code ) {
		return keys.get( code );
	}
	
	function pressKey( code ) {
		var key = getKey( code );
		if ( key != null ) key.press();
	}
	
	function releaseKey( code ) {
		var key = getKey( code );
		if ( key != null ) key.release();
	}
	
	function initKeys() {
		keys = new IntHash<KeyboardKey>();
	}
	
	#if flash9 //-------------------------- AVM2 -------------------------
	
	public function initListener() {
		if (flash.Lib.current.stage != null) {
			flash.Lib.current.stage.removeEventListener(flash.events.KeyboardEvent.KEY_DOWN, onKeyDown );
			flash.Lib.current.stage.removeEventListener(flash.events.KeyboardEvent.KEY_UP, onKeyUp );
			flash.Lib.current.stage.addEventListener(flash.events.KeyboardEvent.KEY_DOWN, onKeyDown );
			flash.Lib.current.stage.addEventListener(flash.events.KeyboardEvent.KEY_UP, onKeyUp );
		}
	}
	
	function onKeyDown(event) {
		pressKey( event.keyCode );
	}
	
	function onKeyUp(event) {
		releaseKey( event.keyCode );
	}
	
	#elseif flash //------------------------------ AVM1 -----------------------------
	
	function initListener() {
		flash.Key.addListener(this);
	}
	
	function onKeyDown() {
		pressKey( Key.getCode() );
	}
	
	function onKeyUp(){
		releaseKey( Key.getCode() );
	}
	
	#end
}